﻿/*  
	------------------------------------------------------------------------
	 NQ Core Library Test Suite
	
	 Homepage: http://www.awzhome.de/
	------------------------------------------------------------------------
	
	This Source Code Form is subject to the terms of the Mozilla Public
	License, v. 2.0. If a copy of the MPL was not distributed with this
	file, You can obtain one at http://mozilla.org/MPL/2.0/.
   
	The Original Code is code of NQ Core Library.

	The Initial Developer of the Original Code is Andreas Weizel.
	Portions created by the Initial Developer are
	Copyright (C) 2012 Andreas Weizel. All Rights Reserved.
	
	Contributor(s): (none)
	
	------------------------------------------------------------------------
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using AWZhome.NQ.Core.Testing;
using AWZhome.NQ.Core.Fluent;

namespace AWZhome.NQ.Core.Tests
{
	[TestFixture]
	public class NQServiceManagerImplFluentInterfaceTest
	{
		private NQServiceManagerImpl _servManager;

		public void SetupManager(NQHostMode hostMode, INQComponentInfo[] compInfos, INQServiceInfo[] servInfos)
		{
			// Initializing of NQ service manager with the dummy component loader
			_servManager = new NQServiceManagerImpl(new string[] { }, hostMode, new NQDummyComponentLoader(compInfos, servInfos));
			NQServiceManager.SetImplementation(_servManager);

			// Load all components in plugin directory	
			_servManager.LoadComponents();
			_servManager.LoadServices();
		}

		[TearDown]
		public void DestroyManager()
		{
			if (_servManager != null)
			{
				_servManager.DestroyServices();
			}
		}

		[Test]
		public void GetService_MustReturnEqualInstances()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo singletonServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple),
				ParentComponent = "TestComponent",
				SingleInstance = true,
				ServiceType = typeof(TestServiceTypeSimple)
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { singletonServ });

			// Two instances of TestService.Singleton returned by GetService() must be the same
			object singleton1 = ServiceCore
				.Get<TestServiceTypeSimple>()
				.To;
			object singleton2 = ServiceCore
				.Get<TestServiceTypeSimple>()
				.To;

			Assert.That(singleton1, Is.EqualTo(singleton2));
		}

		[Test]
		public void CreateAttachedServices_MustNotReturnServicesWithIncompatibleTypes()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo attachListServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst1),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSubst1),
				AttachedTo = new string[]
				{
					"TestService.AttachList/1",
				}
			};
			NQServiceInfo attachListServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple),
				AttachedTo = new string[]
				{
					"TestService.AttachList/1"
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { attachListServ1, attachListServ2 });

			TestServiceTypeSubst1[] attachedServices = ServiceCore
				.RetrieveAttached<TestServiceTypeSubst1>("TestService.AttachList/1")
				.To;

			// The array attachedServices must contain only one element of type TestServiceTypeSubst1
			Assert.That(attachedServices.Length == 1);
			Assert.That(attachedServices[0], Is.TypeOf<TestServiceTypeSubst1>());
		}

		[Test]
		public void GetAttachedServices_MustHandleGivenTypesOfServicesOnly()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo attachListServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple1),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple1),
				AttachedTo = new string[]
				{
					"TestService.AttachList/1",
				}
			};
			NQServiceInfo attachListServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple2),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple2),
				AttachedTo = new string[]
				{
					"TestService.AttachList/1"
				}
			};
			NQServiceInfo attachListSingleServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple3),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple3),
				SingleInstance = true,
				AttachedTo = new string[]
				{
					"TestService.AttachList/1"
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { attachListServ1, attachListServ2, attachListSingleServ });

			// With (true, true) we must get all 3 elements
			TestServiceTypeSimple[] attachedServices1 = ServiceCore
				.RetrieveAttached<TestServiceTypeSimple>("TestService.AttachList/1")
				.WithMultiInstanceServices
				.WithSingleInstanceServices
				.To;
			Assert.That(attachedServices1.Length == 3);

			// With (true, false) we should get only 2 elements (multi-instance services only)
			TestServiceTypeSimple[] attachedServices2 = ServiceCore
				.RetrieveAttached<TestServiceTypeSimple>("TestService.AttachList/1")
				.WithMultiInstanceServices
				.WithoutSingleInstanceServices
				.To;
			Assert.That(attachedServices2.Length == 2);

			// With (false, true) we should get only 1 element (single-instance service only)
			TestServiceTypeSimple[] attachedServices3 = ServiceCore
				.RetrieveAttached<TestServiceTypeSimple>("TestService.AttachList/1")
				.WithoutMultiInstanceServices
				.WithSingleInstanceServices
				.To;
			Assert.That(attachedServices3.Length == 1);
		}

		[Test]
		public void CreateService_MustReturnSubstitutingService()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo substServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst1),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSubst1)
			};
			NQServiceInfo substServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst2),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSubst2)
			};
			NQServiceInfo substServ3 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst3),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSubst3),
				Substitutes = new Type[]
				{
					typeof(TestServiceTypeSubst2)
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { substServ1, substServ2, substServ3 });

			// When standard service substitution works properly, the substitution path
			// SubstitutionTest3 -> SubstitutionTest2
			// defined in NQTestComponent1 should result in an instance of SubstitutionTest3,
			// when referencing SubstitutionTest2!
			object service = ServiceCore
				.Create<TestServiceTypeSubst2>()
				.To;
			Assert.That(service.GetType(), Is.EqualTo(typeof(TestServiceTypeSubst3)));
		}

		[Test]
		public void CreateService_MustReturnSubstitutingServiceHierarchical()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo substServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst1),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSubst1)
			};
			NQServiceInfo substServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst2),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSubst2),
				Substitutes = new Type[]
				{
					typeof(TestServiceTypeSubst1)
				}
			};
			NQServiceInfo substServ3 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst3),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSubst3),
				Substitutes = new Type[]
				{
					typeof(TestServiceTypeSubst2)
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { substServ1, substServ2, substServ3 });

			// When standard service substitution works properly, the substitution path
			// SubstitutionTest3 -> SubstitutionTest2
			// defined in NQTestComponent1 should result in an instance of SubstitutionTest3,
			// when referencing SubstitutionTest2!
			object service = ServiceCore
				.Create<TestServiceTypeSubst1>()
				.To;
			Assert.That(service.GetType(), Is.EqualTo(typeof(TestServiceTypeSubst3)));
		}

		[Test]
		public void GetService_MustReturnSubstitutingService()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo substServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst1),
				ParentComponent = "TestComponent",
				SingleInstance = true,
				ServiceType = typeof(TestServiceTypeSubst1)
			};
			NQServiceInfo substServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst2),
				ParentComponent = "TestComponent",
				SingleInstance = true,
				ServiceType = typeof(TestServiceTypeSubst2)
			};
			NQServiceInfo substServ3 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst3),
				ParentComponent = "TestComponent",
				SingleInstance = true,
				ServiceType = typeof(TestServiceTypeSubst3),
				Substitutes = new Type[]
				{
					typeof(TestServiceTypeSubst2)
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { substServ1, substServ2, substServ3 });

			// When standard service substitution works properly, the substitution path
			// SubstitutionTest3 -> SubstitutionTest2
			// defined in NQTestComponent1 should result in an instance of SubstitutionTest3,
			// when referencing SubstitutionTest2!
			object service = ServiceCore
				.Get<TestServiceTypeSubst2>()
				.To;
			Assert.That(service.GetType(), Is.EqualTo(typeof(TestServiceTypeSubst3)));
		}

		[Test]
		public void GetService_MustReturnSubstitutingServiceHierarchical()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo substServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst1),
				ParentComponent = "TestComponent",
				SingleInstance = true,
				ServiceType = typeof(TestServiceTypeSubst1)
			};
			NQServiceInfo substServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst2),
				ParentComponent = "TestComponent",
				SingleInstance = true,
				ServiceType = typeof(TestServiceTypeSubst2),
				Substitutes = new Type[]
				{
					typeof(TestServiceTypeSubst1)
				}
			};
			NQServiceInfo substServ3 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSubst3),
				ParentComponent = "TestComponent",
				SingleInstance = true,
				ServiceType = typeof(TestServiceTypeSubst3),
				Substitutes = new Type[]
				{
					typeof(TestServiceTypeSubst2)
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { substServ1, substServ2, substServ3 });

			// When standard service substitution works properly, the substitution path
			// SubstitutionTest3 -> SubstitutionTest2
			// defined in NQTestComponent1 should result in an instance of SubstitutionTest3,
			// when referencing SubstitutionTest2!
			object service = ServiceCore
				.Get<TestServiceTypeSubst1>()
				.To;
			Assert.That(service.GetType(), Is.EqualTo(typeof(TestServiceTypeSubst3)));
		}

		[Test]
		public void CreateDependentService_MustPassParentToConstructor()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo parentServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple),
			};
			NQServiceInfo childServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeChild),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeChild),
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { parentServ, childServ });

			// Create TestService.Parent
			TestServiceTypeSimple testParent = ServiceCore
				.Create<TestServiceTypeSimple>()
				.To;

			// Create TestService.Child and pass the instance of TestServiceParent to it
			TestServiceTypeChild testChild = ServiceCore
				.Create<TestServiceTypeChild>()
				.DependentOn<TestServiceTypeSimple>(testParent)
				.To;

			Assert.That(testChild.ParentService, Is.EqualTo(testParent));
		}

		[Test]
		public void CreateDependentService_MustPassParentToInitDependent()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo parentServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple),
			};
			NQServiceInfo childServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeChildProprietary),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeChildProprietary),
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { parentServ, childServ });

			// Create TestService.Parent
			TestServiceTypeSimple testParent = ServiceCore
				.Create<TestServiceTypeSimple>()
				.To;

			// Create TestService.Child and pass the instance of TestServiceParent to it
			TestServiceTypeChildProprietary testChild = ServiceCore
				.Create<TestServiceTypeChildProprietary>()
				.DependentOn<TestServiceTypeSimple>(testParent)
				.To;

			Assert.That(testChild.ParentService, Is.EqualTo(testParent));
		}

		[Test]
		public void CreateDependentServiceDirect_MustPassParentToConstructor()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo parentServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple),
			};
			NQServiceInfo childServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeChild),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeChild),
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { parentServ, childServ });

			// Create TestService.Parent
			TestServiceTypeSimple testParent = ServiceCore
				.Create<TestServiceTypeSimple>()
				.To;

			// Create TestService.Child and pass the instance of TestServiceParent to it
			TestServiceTypeChild testChild = ServiceCore
				.Create<TestServiceTypeChild>()
				.Directly
				.DependentOn<TestServiceTypeSimple>(testParent)
				.To;

			Assert.That(testChild.ParentService, Is.EqualTo(testParent));
		}

		[Test]
		public void CreateDependentServiceDirect_MustPassParentToInitDependent()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo parentServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple),
			};
			NQServiceInfo childServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeChildProprietary),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeChildProprietary),
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { parentServ, childServ });

			// Create TestService.Parent
			TestServiceTypeSimple testParent = ServiceCore
				.Create<TestServiceTypeSimple>()
				.To;

			// Create TestService.Child and pass the instance of TestServiceParent to it
			TestServiceTypeChildProprietary testChild = ServiceCore
				.Create<TestServiceTypeChildProprietary>()
				.Directly
				.DependentOn<TestServiceTypeSimple>(testParent)
				.To;

			Assert.That(testChild.ParentService, Is.EqualTo(testParent));
		}

		[Test]
		public void MustInvokeAndQuitServiceProprietary()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo invokableServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeInvokableProprietary),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeInvokableProprietary),
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { invokableServ });

			INQInvokableService service = ServiceCore
				.Create<TestServiceTypeInvokableProprietary>()
				.Invoke()
				.To;

			// After invoking the service, the OperationPerforming property must be set to true
			Assert.That(((TestServiceTypeInvokableProprietary) service).OperationPerforming);

			// After quitting the operation, the OperationPerforming property must be set back to false
			ServiceCore.From<INQInvokableService>(service).Quit();
			Assert.That(!((TestServiceTypeInvokableProprietary) service).OperationPerforming);
		}

		[Test]
		public void MustInvokeAndQuitService()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};
			NQServiceInfo invokableServ = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeInvokable),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeInvokable),
				InvokeMethod = typeof(TestServiceTypeInvokable).GetMethod("InvokeService"),
				QuitMethod = typeof(TestServiceTypeInvokable).GetMethod("QuitService")
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { invokableServ });

			TestServiceTypeInvokable service = ServiceCore
				.Create<TestServiceTypeInvokable>()
				.Invoke()
				.To;
			// After invoking the service, the OperationPerforming property must be set to true
			Assert.That(service.OperationPerforming);

			// After quitting the operation, the OperationPerforming property must be set back to false
			ServiceCore.From<object>(service).Quit();
			Assert.That(!service.OperationPerforming);
		}

		[Test]
		public void MustAutoInjectServices()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};

			// Services to be injected
			NQServiceInfo injectedServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple1),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple1)
			};
			NQServiceInfo injectedServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple2),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple2),
				AttachedTo = new string[]
				{
					"TestService.AttachList/1"
				}
			};
			NQServiceInfo injectedServ3 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple3),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple3),
				AttachedTo = new string[]
				{
					"TestService.AttachList/1"
				}
			};

			// The service where the services above are injected to
			NQServiceInfo injectionDest = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple[]>),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple[]>),
				AutoInjections = new NQAutoInjection[]
				{
					new NQAutoInjection()
					{
						BoundService = typeof(TestServiceTypeSimple1),
						Interface = typeof(TestServiceTypeSimple)
					},
					new NQAutoInjection()
					{
						BoundAttachList = "TestService.AttachList/1",
						Interface = typeof(TestServiceTypeSimple),
						InjectFromAttachList = true
					}
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { injectionDest, injectedServ1, injectedServ2, injectedServ3 });

			// Now we create an instance of "TestService.InjectionDest" and check, if the service instances have been passed properly
			var autoInjectServ = ServiceCore
				.Create<TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple[]>>()
				.To;

			Assert.That(autoInjectServ.Injection1, Is.Not.Null);
			Assert.That(autoInjectServ.Injection1, Is.TypeOf<TestServiceTypeSimple1>());
			Assert.That(autoInjectServ.Injection2, Is.Not.Null);
			Assert.That(autoInjectServ.Injection2, Is.TypeOf<TestServiceTypeSimple[]>());
			Assert.That(autoInjectServ.Injection2.Length == 2);
		}

		//[Test]
		//public void MustAutoInjectAndPassItselfToDependentServices()
		//{
		//  // Build metadata dummies for the test
		//  NQComponentInfo testComp = new NQComponentInfo()
		//  {
		//    Name = "TestComponent"
		//  };

		//  // Services to be injected
		//  NQServiceInfo injectedServ1 = new NQServiceInfo()
		//  {
		//    ServiceInterface = typeof(TestServiceTypeChild1),
		//    ParentComponent = "TestComponent",
		//    ServiceType = typeof(TestServiceTypeChild1)
		//  };
		//  NQServiceInfo injectedServ2 = new NQServiceInfo()
		//  {
		//    ServiceInterface = typeof(TestServiceTypeChild2),
		//    ParentComponent = "TestComponent",
		//    ServiceType = typeof(TestServiceTypeChild2),
		//    AttachedTo = new string[]
		//    {
		//      "TestService.AttachList/1"
		//    }
		//  };
		//  NQServiceInfo injectedServ3 = new NQServiceInfo()
		//  {
		//    ServiceInterface = typeof(TestServiceTypeChild3),
		//    ParentComponent = "TestComponent",
		//    ServiceType = typeof(TestServiceTypeChild3),
		//    AttachedTo = new string[]
		//    {
		//      "TestService.AttachList/1"
		//    }
		//  };

		//  // The service where the services above are injected to
		//  NQServiceInfo injectionDest = new NQServiceInfo()
		//  {
		//    ServiceInterface = typeof(TestServiceTypeAutoInjection2<TestServiceTypeChild, TestServiceTypeChild[]>),
		//    ParentComponent = "TestComponent",
		//    ServiceType = typeof(TestServiceTypeAutoInjection2<TestServiceTypeChild, TestServiceTypeChild[]>),
		//    AutoInjections = new NQAutoInjection[]
		//    {
		//      new NQAutoInjection()
		//      {
		//        BoundService = typeof(TestServiceTypeChild1),
		//        Interface = typeof(TestServiceTypeChild),
		//        InjectAsDependent = true
		//      },
		//      new NQAutoInjection()
		//      {
		//        BoundAttachList = "TestService.AttachList/1",
		//        Interface = typeof(TestServiceTypeChild),
		//        InjectFromAttachList = true,
		//        InjectAsDependent = true
		//      }
		//    }
		//  };

		//  this.SetupManager(NQHostMode.Console,
		//    new INQComponentInfo[] { testComp },
		//    new INQServiceInfo[] { injectionDest, injectedServ1, injectedServ2, injectedServ3 });

		//  // Now we create an instance of "TestService.InjectionDest" and check, if the service instances have been passed properly
		//  var autoInjectServ = ServiceCore
		//    .Create<TestServiceTypeAutoInjection2<TestServiceTypeChild, TestServiceTypeChild[]>>()
		//    .To;

		//  Assert.That(autoInjectServ.Injection1.ParentService, Is.EqualTo(autoInjectServ));
		//  Assert.That(autoInjectServ.Injection2[0], Is.EqualTo(autoInjectServ));
		//}

		[Test(Description = "When Override parameter is not set, handle services passed through CreateDependentService() independently from auto-injection.")]
		public void MustAutoInjectThroughCreateDependentServiceWithoutOverride()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};

			// Services to be injected
			NQServiceInfo injectedServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple)
			};

			// The service where the services above are injected to
			NQServiceInfo injectionDest = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>),
				AutoInjections = new NQAutoInjection[]
				{
					new NQAutoInjection()
					{
						BoundService = typeof(TestServiceTypeSimple),
						Interface = typeof(TestServiceTypeSimple)
					}
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { injectionDest, injectedServ1 });

			// Firstly we create a parent service, that we can pass (= inject) into "TestService.InjectionDest"
			var parentServ = ServiceCore
				.Create<TestServiceTypeSimple>()
				.To;

			// Now we create an instance of "TestService.InjectionDest" as a dependent service and check,
			// if parentServ has been injected properly.
			var autoInjectServ = ServiceCore
				.Create<TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>>()
				.DependentOn<TestServiceTypeSimple>(parentServ)
				.To;

			Assert.That(autoInjectServ.Injection1, Is.EqualTo(parentServ));
		}

		[Test(Description = "When Override parameter is set, auto-inject services passed through CreateDependentService(). First parameter is overridable.")]
		public void MustAutoInjectThroughCreateDependentServiceWithOverrideAsFirst()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};

			// Services to be injected
			NQServiceInfo injectedServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple1),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple1)
			};
			NQServiceInfo injectedServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple2),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple2)
			};

			// The service where the services above are injected to
			NQServiceInfo injectionDest = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>),
				AutoInjections = new NQAutoInjection[]
				{
					new NQAutoInjection()
					{
						BoundService = typeof(TestServiceTypeSimple1),
						Interface = typeof(TestServiceTypeSimple),
						Overridable = true
					},
					new NQAutoInjection()
					{
						BoundService = typeof(TestServiceTypeSimple2),
						Interface = typeof(TestServiceTypeSimple)
					}
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { injectionDest, injectedServ1, injectedServ2 });

			// Firstly we create a parent service, that we can pass (= inject) into "TestService.InjectionDest"
			var parentServ = ServiceCore
				.Create<TestServiceTypeSimple1>()
				.To;

			// Now we create an instance of "TestService.InjectionDest" as a dependent service and check,
			// if parentServ has been injected properly.
			var autoInjectServ = ServiceCore
				.Create<TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>>()
				.DependentOn<TestServiceTypeSimple>(parentServ)
				.To;

			Assert.That(autoInjectServ.Injection1, Is.EqualTo(parentServ));
		}

		[Test(Description = "When Override parameter is set, auto-inject services passed through CreateDependentService(). Second parameter is overridable.")]
		public void MustAutoInjectThroughCreateDependentServiceWithOverrideAsSecond()
		{
			// Build metadata dummies for the test
			NQComponentInfo testComp = new NQComponentInfo()
			{
				Name = "TestComponent"
			};

			// Services to be injected
			NQServiceInfo injectedServ1 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple1),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple1)
			};
			NQServiceInfo injectedServ2 = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeSimple2),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeSimple2)
			};

			// The service where the services above are injected to
			NQServiceInfo injectionDest = new NQServiceInfo()
			{
				ServiceInterface = typeof(TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>),
				ParentComponent = "TestComponent",
				ServiceType = typeof(TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>),
				AutoInjections = new NQAutoInjection[]
				{
					new NQAutoInjection()
					{
						BoundService = typeof(TestServiceTypeSimple1),
						Interface = typeof(TestServiceTypeSimple),
					},
					new NQAutoInjection()
					{
						BoundService = typeof(TestServiceTypeSimple2),
						Interface = typeof(TestServiceTypeSimple),
						Overridable = true
					}
				}
			};

			this.SetupManager(NQHostMode.Console,
				new INQComponentInfo[] { testComp },
				new INQServiceInfo[] { injectionDest, injectedServ1, injectedServ2 });

			// Firstly we create a parent service, that we can pass (= inject) into "TestService.InjectionDest"
			var parentServ = ServiceCore
				.Create<TestServiceTypeSimple2>()
				.To;

			// Now we create an instance of "TestService.InjectionDest" as a dependent service and check,
			// if parentServ has been injected properly.
			var autoInjectServ = ServiceCore
				.Create<TestServiceTypeAutoInjection2<TestServiceTypeSimple, TestServiceTypeSimple>>()
				.DependentOn<TestServiceTypeSimple>(parentServ)
				.To;

			Assert.That(autoInjectServ.Injection2, Is.EqualTo(parentServ));
		}
	}
}
